﻿using CTP.CRM.Core.Common.Dto;
using CTP.CRM.Core.Redis;
using FreeRedis;
using Microsoft.Extensions.Primitives;
using NUglify.Helpers;
using System.Reflection;

namespace CTP.CRM.Core.Language
{
    public static class LanguageHelper
    {
        private static MasterDataLanguageOptions _masterDataLanguageOptions;

        internal static void Init(MasterDataLanguageOptions masterDataLanguageOptions)
        {
            _masterDataLanguageOptions = masterDataLanguageOptions;
        }

        //
        // 摘要:
        //     语言转换
        //
        // 参数:
        //   data:
        //     分页数据
        //
        // 类型参数:
        //   T:
        public static void LanguageConversion<T>(this UnifyPageResultDto<T> data) where T : class
        {
            if (data != null && data.List != null && data.List.Any() && _masterDataLanguageOptions != null && !string.IsNullOrWhiteSpace(_masterDataLanguageOptions.LanguageHeaderKey))
            {
                StringValues? stringValues = CTPABPCore.HttpContext?.Request?.Headers[_masterDataLanguageOptions.LanguageHeaderKey];
                string text = (stringValues.HasValue ? ((string?)stringValues.GetValueOrDefault()) : null) + string.Empty;
                if (!string.IsNullOrWhiteSpace(text))
                {
                    Type typeFromHandle = typeof(T);
                    List<string> dynamicEnumProperty = GetDynamicEnumProperty(typeFromHandle, data.List.ToArray());
                    Dictionary<string, Dictionary<string, string>> languageHashValues = GetLanguageHashValues(typeFromHandle, text, dynamicEnumProperty);
                    LanguageConversion(languageHashValues, text, data.List.ToArray());
                }
            }
        }

        //
        // 摘要:
        //     语言转换
        //
        // 参数:
        //   data:
        //     List集合数据
        //
        // 类型参数:
        //   T:
        public static void LanguageConversion<T>(this List<T> data) where T : class
        {
            if (data != null && data.Any() && _masterDataLanguageOptions != null && _masterDataLanguageOptions != null && !string.IsNullOrWhiteSpace(_masterDataLanguageOptions.LanguageHeaderKey))
            {
                StringValues? stringValues = CTPABPCore.HttpContext?.Request?.Headers[_masterDataLanguageOptions.LanguageHeaderKey];
                string text = (stringValues.HasValue ? ((string?)stringValues.GetValueOrDefault()) : null) + string.Empty;
                if (!string.IsNullOrWhiteSpace(text))
                {
                    Type typeFromHandle = typeof(T);
                    List<string> dynamicEnumProperty = GetDynamicEnumProperty(typeFromHandle, data.ToArray());
                    Dictionary<string, Dictionary<string, string>> languageHashValues = GetLanguageHashValues(typeFromHandle, text, dynamicEnumProperty);
                    LanguageConversion(languageHashValues, text, data.ToArray());
                }
            }
        }

        //
        // 摘要:
        //     语言转换
        //
        // 参数:
        //   data:
        //     单条数据
        //
        // 类型参数:
        //   T:
        public static void LanguageConversion<T>(this T data) where T : class
        {
            if (data != null && _masterDataLanguageOptions != null && _masterDataLanguageOptions != null && !string.IsNullOrWhiteSpace(_masterDataLanguageOptions.LanguageHeaderKey))
            {
                StringValues? stringValues = CTPABPCore.HttpContext?.Request?.Headers[_masterDataLanguageOptions.LanguageHeaderKey];
                string text = (stringValues.HasValue ? ((string?)stringValues.GetValueOrDefault()) : null) + string.Empty;
                if (!string.IsNullOrWhiteSpace(text))
                {
                    Type typeFromHandle = typeof(T);
                    List<string> dynamicEnumProperty = GetDynamicEnumProperty<T>(typeFromHandle, data);
                    Dictionary<string, Dictionary<string, string>> languageHashValues = GetLanguageHashValues(typeFromHandle, text, dynamicEnumProperty);
                    LanguageConversion<T>(languageHashValues, text, data);
                }
            }
        }

        //
        // 摘要:
        //     获取动态枚举属性
        //
        // 参数:
        //   tType:
        //
        //   list:
        //
        // 类型参数:
        //   T:
        private static List<string> GetDynamicEnumProperty<T>(Type tType, params T[] list)
        {
            List<string> list2 = new List<string>();
            bool flag = false;
            if (tType.GetProperties().Any((PropertyInfo t) => (t.GetCustomAttribute(typeof(MasterDataLanguageAttribute)) as MasterDataLanguageAttribute)?.IsDynamicEnumProperty ?? false))
            {
                flag = true;
            }

            if (!flag)
            {
                return list2;
            }

            for (int i = 0; i < list.Length; i++)
            {
                T val = list[i];
                PropertyInfo[] properties = val.GetType().GetProperties();
                PropertyInfo[] array = properties;
                foreach (PropertyInfo element in array)
                {
                    MasterDataLanguageAttribute attribute = element.GetCustomAttribute(typeof(MasterDataLanguageAttribute)) as MasterDataLanguageAttribute;
                    if (attribute == null)
                    {
                        continue;
                    }

                    bool flag2 = attribute.TableName.Equals("t_enum_value_info", StringComparison.OrdinalIgnoreCase);
                    if (flag2 && attribute.IsDynamicEnumProperty && (!flag2 || !string.IsNullOrWhiteSpace(attribute.EnumProperty)))
                    {
                        string text = (properties.FirstOrDefault((PropertyInfo x) => x.Name.ToLower() == attribute.EnumProperty?.ToLower())?.GetValue(val, null))?.ToString() + string.Empty;
                        if (!string.IsNullOrEmpty(text) && !list2.Contains(text))
                        {
                            list2.Add(text);
                        }
                    }
                }
            }

            return list2;
        }

        //
        // 摘要:
        //     获取语言缓存
        //
        // 参数:
        //   tType:
        //
        //   language:
        //
        //   enumPropertys:
        private static Dictionary<string, Dictionary<string, string>> GetLanguageHashValues(Type tType, string language, List<string> enumPropertys)
        {
            Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>();
            PropertyInfo[] properties = tType.GetProperties();
            bool flag = false;
            PropertyInfo[] array = properties;
            foreach (PropertyInfo propertyInfo in array)
            {
                if (!(propertyInfo.GetCustomAttribute(typeof(MasterDataLanguageAttribute)) is MasterDataLanguageAttribute masterDataLanguageAttribute))
                {
                    continue;
                }

                if (string.IsNullOrEmpty(masterDataLanguageAttribute.FieldName))
                {
                    masterDataLanguageAttribute.FieldName = propertyInfo.Name;
                }

                bool flag2 = masterDataLanguageAttribute.TableName.Equals("t_enum_value_info", StringComparison.OrdinalIgnoreCase);
                if (flag2 && string.IsNullOrWhiteSpace(masterDataLanguageAttribute.EnumProperty))
                {
                    continue;
                }

                string text = (masterDataLanguageAttribute.IsLanguageKeyMode ? _masterDataLanguageOptions.LanguageCacheKey : _masterDataLanguageOptions.MasterdataItemLanguageCacheKey) + ":" + (masterDataLanguageAttribute.IsLanguageKeyMode ? (masterDataLanguageAttribute.LanguageProjectCode + ":") : "") + (masterDataLanguageAttribute.IsLanguageKeyMode ? "" : (masterDataLanguageAttribute.TableName.ToLower() + ":")) + (masterDataLanguageAttribute.IsLanguageKeyMode ? "" : (masterDataLanguageAttribute.FieldName?.ToLower() + ":")) + language;
                if (dictionary.ContainsKey(text))
                {
                    continue;
                }

                Dictionary<string, string> dictionary2 = null;
                using (RedisClient.DatabaseHook databaseHook = RedisHelper.Client.GetDatabase(_masterDataLanguageOptions.MasterdataItemLanguageDbIndex))
                {
                    dictionary2 = databaseHook.HGetAll(text);
                }

                if (dictionary2 == null)
                {
                    continue;
                }

                if (flag2 && dictionary2.Count > 0)
                {
                    if (masterDataLanguageAttribute.IsDynamicEnumProperty && !flag)
                    {
                        foreach (string enumProperty in enumPropertys)
                        {
                            string key = text + ":" + enumProperty.ToLower();
                            if (!dictionary.ContainsKey(key))
                            {
                                Dictionary<string, string> dictionary3 = SetEnumValueInfo(enumProperty, dictionary2);
                                if (dictionary3.Count > 0)
                                {
                                    dictionary.Add(key, dictionary3);
                                }
                            }
                        }

                        flag = true;
                        continue;
                    }

                    if (!masterDataLanguageAttribute.IsDynamicEnumProperty)
                    {
                        text = text + ":" + masterDataLanguageAttribute.EnumProperty?.ToLower();
                        if (dictionary.ContainsKey(text))
                        {
                            continue;
                        }

                        dictionary2 = SetEnumValueInfo(masterDataLanguageAttribute.EnumProperty, dictionary2);
                    }
                }

                if (!masterDataLanguageAttribute.IsDynamicEnumProperty && dictionary2.Count > 0)
                {
                    dictionary.Add(text, dictionary2);
                }
            }

            return dictionary;
        }

        //
        // 摘要:
        //     语言内容替换
        //
        // 参数:
        //   list:
        //
        //   languageHashValues:
        //
        //   language:
        //
        // 类型参数:
        //   T:
        private static void LanguageConversion<T>(Dictionary<string, Dictionary<string, string>> languageHashValues, string language, params T[] list) where T : class
        {
            Dictionary<string, Dictionary<string, string>> languageHashValues2 = languageHashValues;
            if (languageHashValues2.Count == 0)
            {
                return;
            }

            foreach (T val in list)
            {
                PropertyInfo[] properties = val.GetType().GetProperties();
                PropertyInfo[] array = properties;
                foreach (PropertyInfo propertyInfo in array)
                {
                    MasterDataLanguageAttribute attribute = propertyInfo.GetCustomAttribute(typeof(MasterDataLanguageAttribute)) as MasterDataLanguageAttribute;
                    if (attribute == null)
                    {
                        continue;
                    }

                    object obj = (attribute.IsLanguageKeyMode ? propertyInfo.GetValue(val, null) : properties.FirstOrDefault((PropertyInfo x) => x.Name.ToLower() == attribute.PrimaryKeyName.ToLower())?.GetValue(val, null));
                    string id = obj?.ToString() + string.Empty;
                    if (obj == null || string.IsNullOrWhiteSpace(id))
                    {
                        continue;
                    }

                    if (obj.GetType().IsEnum)
                    {
                        id = (int)obj + string.Empty;
                    }

                    bool flag = attribute.TableName.Equals("t_enum_value_info", StringComparison.OrdinalIgnoreCase);
                    if (flag && string.IsNullOrWhiteSpace(attribute.EnumProperty))
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(attribute.FieldName))
                    {
                        attribute.FieldName = propertyInfo.Name;
                    }

                    string languageCacheKey = (attribute.IsLanguageKeyMode ? _masterDataLanguageOptions.LanguageCacheKey : _masterDataLanguageOptions.MasterdataItemLanguageCacheKey) + ":" + (attribute.IsLanguageKeyMode ? (attribute.LanguageProjectCode + ":") : "") + (attribute.IsLanguageKeyMode ? "" : (attribute.TableName.ToLower() + ":")) + (attribute.IsLanguageKeyMode ? "" : (attribute.FieldName?.ToLower() + ":")) + language;
                    string value = string.Empty;
                    if (flag)
                    {
                        if (attribute.IsDynamicEnumProperty)
                        {
                            string text = (properties.FirstOrDefault((PropertyInfo x) => x.Name.ToLower() == attribute.EnumProperty?.ToLower())?.GetValue(val, null))?.ToString() + string.Empty;
                            if (string.IsNullOrEmpty(text))
                            {
                                continue;
                            }

                            languageCacheKey = languageCacheKey + ":" + text.ToLower();
                        }
                        else
                        {
                            languageCacheKey = languageCacheKey + ":" + attribute.EnumProperty?.ToLower();
                        }

                        if (!languageHashValues2.ContainsKey(languageCacheKey))
                        {
                            continue;
                        }

                        List<string> source = languageHashValues2[languageCacheKey].Keys.ToList();
                        if (!attribute.IsBitOperation)
                        {
                            if (!languageHashValues2[languageCacheKey].ContainsKey(id))
                            {
                                continue;
                            }

                            value = languageHashValues2[languageCacheKey][id];
                        }
                        else if (attribute.IsBitOperation && source.Any((string t) => (int.Parse(t) & int.Parse(id)) > 0))
                        {
                            List<string> values = new List<string>();
                            source.Where((string t) => (int.Parse(t) & int.Parse(id)) > 0).ForEach(delegate (string t)
                            {
                                values.Add(languageHashValues2[languageCacheKey][t]);
                            });
                            value = string.Join(",", values);
                        }
                    }
                    else
                    {
                        if (!languageHashValues2.ContainsKey(languageCacheKey) || !languageHashValues2[languageCacheKey].ContainsKey(id))
                        {
                            continue;
                        }

                        value = languageHashValues2[languageCacheKey][id];
                    }

                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        propertyInfo.SetValue(val, value);
                    }
                }
            }
        }

        //
        // 摘要:
        //     枚举数据处理
        //
        // 参数:
        //   enumProperty:
        //     枚举属性
        //
        //   hashValues:
        //     缓存数据
        private static Dictionary<string, string> SetEnumValueInfo(string enumProperty, Dictionary<string, string> hashValues)
        {
            Dictionary<string, string> hashValues2 = hashValues;
            Dictionary<string, string> newHashValues = new Dictionary<string, string>();
            if (hashValues2.Count == 0)
            {
                return newHashValues;
            }

            string key = "t_enum_value_info:" + enumProperty.ToLower();
            Dictionary<string, string> collection = null;
            using (RedisClient.DatabaseHook databaseHook = RedisHelper.Client.GetDatabase(_masterDataLanguageOptions.MasterdataItemLanguageDbIndex))
            {
                collection = databaseHook.HGetAll(key);
            }

            collection.ForEach(delegate (KeyValuePair<string, string> t)
            {
                if (hashValues2.ContainsKey(t.Value))
                {
                    newHashValues.Add(t.Key, hashValues2[t.Value]);
                }
            });
            return newHashValues;
        }
    }
}
